package com.jhgsys.internal.base.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jhgsys.internal.base.dto.BaseAreDto;
import com.jhgsys.internal.base.dto.BaseAreaSchedulingInfoDto;
import com.jhgsys.internal.base.entity.BaseArea;
import com.jhgsys.internal.base.entity.BaseAreaScheduling;
import com.jhgsys.internal.base.entity.BaseProject;
import com.jhgsys.internal.base.mapper.BaseAreaMapper;
import com.jhgsys.internal.base.service.IBaseAreaSchedulingService;
import com.jhgsys.internal.base.service.IBaseAreaService;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.common.utils.DateUtil;
import com.jhgsys.internal.common.utils.FebsUtil;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 区域设置 Service实现
 *
 * @author admin
 * @date 2024-07-31 14:35:47
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BaseAreaServiceImpl extends ServiceImpl<BaseAreaMapper, BaseArea> implements IBaseAreaService {

    @Autowired
    private IBaseAreaSchedulingService areaSchedulingService;

    /**
     * 查询（分页）
     * @author admin
     * @date 2024-07-31 14:35:47
     * @param request QueryRequest
     * @param baseArea baseArea
     * @return IPage<BaseArea>
    */
    @Override
    public IPage<BaseAreDto> findBaseAreaPage(QueryRequest request, BaseAreDto baseArea) {
        Page<BaseAreDto> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<BaseAreDto>  pageinfo = this.baseMapper.selectAreaPage(page,baseArea);
        return pageinfo;
    }

    @Override
    public IPage<Map<String, Object>> findbaseAreaSchedulingInfoPage(QueryRequest request, BaseAreDto baseArea ,Date startDate, Date  endDate) {
        IPage<Map<String, Object>> resultPage = new Page<>();
        List<Map<String,Object>> tableData = new ArrayList<>();
        Map<String, Object> dataTable = new HashedMap();
         IPage<BaseAreDto> pageArea = this.findBaseAreaPage(request,baseArea);
        List<BaseAreDto> areaList = pageArea.getRecords();
        //获取所有区域ID
        List<String> areaIdList = new ArrayList<>();
        if(StringUtils.isBlank(baseArea.getAreaId())){
            areaIdList = areaList.stream().map(BaseArea::getAreaId).collect(Collectors.toList());
        }else{
            areaIdList.add(baseArea.getAreaId());
        }
        if(CollectionUtils.isEmpty(areaIdList)){
            //没有区域信息
            resultPage.setRecords(null);
            resultPage.setTotal(pageArea.getTotal());
            return resultPage;
        }

        LambdaQueryWrapper<BaseAreaScheduling> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseAreaScheduling::getDeletedFlg,0);
        queryWrapper.in(BaseAreaScheduling::getAreaId,areaIdList);
        if(startDate != null && endDate!=null){
            queryWrapper.between(BaseAreaScheduling::getSchedulingDate,startDate,endDate);
        }
        if(startDate == null && endDate !=null){
            queryWrapper.le(BaseAreaScheduling::getSchedulingDate,endDate);
        }
        if(startDate != null && endDate == null){
            queryWrapper.ge(BaseAreaScheduling::getSchedulingDate,startDate);
        }
        queryWrapper.eq(BaseAreaScheduling::getDeletedFlg,FebsConstant.VALID);
        queryWrapper.orderByAsc(BaseAreaScheduling::getCreatedTime);


        //根据区域获取对应排班信息
        List<BaseAreaScheduling> schedulingList = areaSchedulingService.list(queryWrapper);

        /*if(CollectionUtils.isEmpty(schedulingList)){
            areaList.forEach(item->{
                tableData.add(getRowData(item,"1"));
                tableData.add(getRowData(item,"2"));
                tableData.add(getRowData(item,"3"));

            });
            resultPage.setRecords(tableData);
            resultPage.setTotal(pageArea.getTotal());
            return resultPage;
        }*/

        //字段转换
        List<BaseAreaSchedulingInfoDto> listDto = new ArrayList<>();
        schedulingList.forEach(item->{
            BaseAreaSchedulingInfoDto dto = new BaseAreaSchedulingInfoDto();
            dto.setSchedulingDate(DateUtil.getDateFormat(item.getSchedulingDate(),DateUtil.YYYY_MM_DD_PATTERN));
            dto.setSchedulingName(item.getSchedulingName());
            dto.setSchedulingTime(item.getSchedulingTime());
            dto.setSchedulingType(item.getSchedulingType());
            dto.setRealName(item.getRealName());
            dto.setAreaId(item.getAreaId());
            listDto.add(dto);
        });

        List<String> schedulingDates = listDto.stream().map(BaseAreaSchedulingInfoDto::getSchedulingDate).distinct().collect(Collectors.toList());
        areaList.forEach(area->{
            List<BaseAreaSchedulingInfoDto> areaScheList = listDto.stream()
                    .filter(item->item.getAreaId().equals(area.getAreaId())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(areaScheList)){
                List<Map<String,Object>> list = getBuildData(schedulingDates,areaScheList);
                list.forEach(m->{
                    m.put("areaName",area.getAreaName());
                    m.put("areaId",area.getAreaId());
                    m.put("sort",area.getSort());
                    if(area.getCreatedTime()!=null){
                        m.put("createTime", DateUtil.getDateFormat(area.getCreatedTime(),DateUtil.YYYY_MM_DD_PATTERN));
                    }
                });
                tableData.addAll(list);
            }else {
                //没有排班信息
                Map<String,Object> rowData = new HashedMap();
//                tableData.add(rowData);
                tableData.add(getRowData(area,""));
            }
        });
        resultPage.setRecords(tableData);
        resultPage.setTotal(pageArea.getTotal());
        return resultPage;
    }

    /**
     * 组装排班信息行数据
     * @param baseArea
     * @param schedulingType
     * @return
     */
    private Map<String,Object> getRowData(BaseArea baseArea,String schedulingType){
        Map<String,Object> rowData = new HashedMap();
        rowData.put("areaName",baseArea.getAreaName());
        rowData.put("areaId",baseArea.getAreaId());
        rowData.put("sort",baseArea.getSort());
        if(baseArea.getCreatedTime()!=null){
            rowData.put("createTime", DateUtil.getDateFormat(baseArea.getCreatedTime(),DateUtil.YYYY_MM_DD_PATTERN));
        }

        rowData.put("schedulingDate","");
        rowData.put("schedulingName","");
        rowData.put("schedulingTime","");
        return rowData;
    }


    /**
     * 查询（所有）
     * @author admin
     * @date 2024-07-31 14:35:47
     * @param baseArea baseArea
     * @return List<BaseArea>
     */
    @Override
    public List<BaseArea> findBaseAreaList(BaseArea baseArea) {
	    LambdaQueryWrapper<BaseArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseArea::getDeletedFlg, FebsConstant.VALID);
        if(StringUtils.isNotBlank(baseArea.getTenantId())){
            queryWrapper.eq(BaseArea::getTenantId,baseArea.getTenantId());
        }
        if(StringUtils.isNotBlank(baseArea.getAreaId())){
            List<String> list = Arrays.asList(baseArea.getAreaId().split(StringPool.COMMA));
            queryWrapper.in(BaseArea::getAreaId,list);
        }

        if(StringUtils.isNotBlank(baseArea.getStatus())){
            queryWrapper.eq(BaseArea::getStatus,baseArea.getStatus());
        }
		return this.baseMapper.selectList(queryWrapper);
    }



    /**
    * 根据ID查询
    * @author admin
    * @date 2024-07-31 14:35:47
    * @param id
    * @return BaseArea
    */
    @Override
    public BaseArea findBaseAreaById(String id){
        return this.baseMapper.selectById(id);
    }

    /**
     * 新增
     * @author admin
     * @date 2024-07-31 14:35:47
     * @param baseArea baseArea
     */
    @Override
    @Transactional
    public void createBaseArea(BaseArea baseArea) {
        baseArea.setCreatedTime(new Date());
        this.save(baseArea);
//        Date schedulingDate = DateUtil.parseDate(baseArea.getSchedulingDate(),DateUtil.YYYY_MM_DD_PATTERN);
//        BaseAreaScheduling morning = baseArea.getMorningMan();
//        morning.setAreaId(baseArea.getAreaId());
//        morning.setCreatedBy(baseArea.getCreatedBy());
//        morning.setCreatedTime(new Date());
//        morning.setDeletedFlg(FebsConstant.VALID);
//        morning.setSchedulingDate(baseArea.getSchedulingDate());
//        morning.setSchedulingType("1");
//        areaSchedulingService.save(morning);
//        BaseAreaScheduling middle = baseArea.getMiddleMan();
//        middle.setAreaId(baseArea.getAreaId());
//        middle.setCreatedBy(baseArea.getCreatedBy());
//        middle.setCreatedTime(new Date());
//        middle.setDeletedFlg(FebsConstant.VALID);
//        middle.setSchedulingDate(baseArea.getSchedulingDate());
//        middle.setSchedulingType("2");
//        areaSchedulingService.save(middle);
//        BaseAreaScheduling night = baseArea.getNightMan();
//        night.setAreaId(baseArea.getAreaId());
//        night.setCreatedBy(baseArea.getCreatedBy());
//        night.setCreatedTime(new Date());
//        night.setDeletedFlg(FebsConstant.VALID);
//        night.setSchedulingDate(baseArea.getSchedulingDate());
//        night.setSchedulingType("3");
//        areaSchedulingService.save(night);

    }

    /**
     * 修改
     * @author admin
     * @date 2024-07-31 14:35:47
     * @param baseArea baseArea
     */
    @Override
    @Transactional
    public void updateBaseArea(BaseArea baseArea) {
        baseArea.setUpdatedTime(new Date());
        this.saveOrUpdate(baseArea);
    }

    /**
     * 逻辑删除
     * @author admin
     * @date 2024-07-31 14:35:47
     * @param baseArea baseArea
     * @param baseAreaIds baseAreaIds
     */
    @Override
    @Transactional
    public void deleteBaseArea(BaseArea baseArea,String baseAreaIds) {
        List<String> list = Arrays.asList(baseAreaIds.split(StringPool.COMMA));
        this.baseMapper.update(baseArea,new LambdaQueryWrapper<BaseArea>().in(BaseArea::getAreaId,list));
	}

    /**
    * 物理删除
    * @author admin
    * @date 2024-07-31 14:35:47
    * @param baseAreaIds baseAreaIds
    */
    @Override
    @Transactional
    public void physicallyDeleteBaseArea(String baseAreaIds) {
        List<String> list = Arrays.asList(baseAreaIds.split(StringPool.COMMA));
        LambdaQueryWrapper<BaseArea> wapper = new LambdaQueryWrapper<>();
        wapper.in(BaseArea::getAreaId,list);
        this.remove(wapper);
    }

    /**
     * 组装排版总览数据
     * @param schedulingDates
     * @param areaSchedulingInfoDtos
     * @return
     */
    public List<Map<String,Object>> getBuildData(List<String> schedulingDates,List<BaseAreaSchedulingInfoDto> areaSchedulingInfoDtos){
        List<Map<String,Object>> tableData = new ArrayList<>();
        List<List<BaseAreaSchedulingInfoDto>> dateList = new ArrayList<>();
        schedulingDates.forEach(date->{
            List<BaseAreaSchedulingInfoDto> areaScheList = areaSchedulingInfoDtos.stream()
                    .filter(item->item.getSchedulingDate().equals(date)).collect(Collectors.toList());
            //对当天数据进行排序
            if(!CollectionUtils.isEmpty(areaScheList) && areaScheList.size()>1){
                for(int i=0;i<areaScheList.size()-1;i++){
                    for(int j=0;j< areaScheList.size()-i-1;j++){
                        BaseAreaSchedulingInfoDto d1 = areaScheList.get(j);
                        BaseAreaSchedulingInfoDto d2 = areaScheList.get(j+1);
                        int time1 = getTimeNumber(d1.getSchedulingTime());
                        int time2 = getTimeNumber(d2.getSchedulingTime());
                        if(time1>time2){
                            BaseAreaSchedulingInfoDto temp = d1;
                            areaScheList.set(j,d2);
                            areaScheList.set(j+1,temp);
                        }
                    }

                }
            }
            dateList.add(areaScheList);
        });

        List<BaseAreaSchedulingInfoDto> maxList = new ArrayList<>();
        for(List<BaseAreaSchedulingInfoDto> list:dateList){
            if(maxList.size()<list.size()){
                maxList = list;
            }
        }
        int max = maxList.size();
        for (int i = 0; i < max; ) {
            Map<String, Object> m = new HashMap<>();
            int p=0;
            for (int j = 0; j < dateList.size(); j++) {
                List<BaseAreaSchedulingInfoDto> list = dateList.get(j);
                if (list.size() > 0) {
                    if (i < list.size()) {
                        m.put("schedulingName" + schedulingDates.get(p), list.get(i).getSchedulingName());
                        m.put("schedulingTime" + schedulingDates.get(p), list.get(i).getSchedulingTime());
                        m.put("schedulingUser" + schedulingDates.get(p), list.get(i).getRealName());
                    } else {
                        m.put("schedulingName" + schedulingDates.get(p), "");
                        m.put("schedulingTime" + schedulingDates.get(p), "");
                        m.put("schedulingUser" + schedulingDates.get(p), "");
                    }
                } else {
                    m.put("schedulingName" + schedulingDates.get(p), "");
                    m.put("schedulingTime" + schedulingDates.get(p), "");
                    m.put("schedulingUser" + schedulingDates.get(p), "");
                }
                p++;
            }
            boolean isEmpty = false;
            int emptyCount = 0;
            for (Map.Entry<String, Object> entry : m.entrySet()) {
                if (entry.getValue() == null || entry.getValue() == "") {
                    emptyCount++;
                }
            }
            if (emptyCount == m.size()) {
                isEmpty = true;
            }
            if (!isEmpty) {
                tableData.add(m);
            }
            i++;
        }
        return tableData;
    }

    /**
     * 获取时间前两位转换为int
     * @param time
     * @return
     */
    public int getTimeNumber(String time){
        int timeNumber = 0;
        if(StringUtils.isNotBlank(time)){
            time = time.substring(0,2);
            if(time.startsWith("0")){
                time = time.substring(1,2);
            }
            timeNumber = Integer.parseInt(time);
        }
        return timeNumber;
    }

}
